/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the robot4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */

package com.hitqz.robot.daemon.quartz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.cache.Cache;
import com.google.common.collect.Lists;
import com.hitqz.robot.api.business.dto.RobotClientSummaryDto;
import com.hitqz.robot.api.business.dto.SubscriptTopicDto;
import com.hitqz.robot.api.business.entity.*;
import com.hitqz.robot.api.dispatch.protocol.dto.FormConfigModalDto;
import com.hitqz.robot.api.dispatch.protocol.dto.FormFieldConfigModalDto;
import com.hitqz.robot.api.dispatch.protocol.dto.RobotNextStepDto;
import com.hitqz.robot.biz.service.*;
import com.hitqz.robot.common.core.util.R;
import com.hitqz.robot.daemon.quartz.dao.AgvDao;
import com.hitqz.robot.daemon.quartz.model.*;
import com.hitqz.robot.daemon.quartz.service.SysJobService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.SchedulerException;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author guoliang
 * @date 2024-3-26 11:19:18
 * <p>
 * 定时任务管理
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("")
//@Tag(description = "sys-job", name = "agv")
@Tag(name = "AGV呼叫系统--哈尔滨车辆段")
@Slf4j
public class AgvController {

	private final AgvDao agvDao;

	private final RobotJobService robotJobService;

	private final SysJobService sysJobService;

	private final RestTemplate restTemplate;

	private final RobotService robotService;

	private final GoodsBuffersService goodsBuffersService;

	private final GoodsGroupService  goodsGroupService;

	private final JobCachesService jobCachesService;

	// 等待通知接口为 /agv/arriveResponse
	// 任务流程： 轮对。 轮对左/右(911008/911007)  轮对校验取前置点(911016) 等待通知 然后前往(911009) 放下后到达 轮对校验取前置点(911016) 通知 缓存完成
    // 911008 南面 911007 北面
	/**
	 *   已经不需要 报废-缓存: 前往报废架前置点(911004)，等待通知下一步报废架(911015)，前往报废架前置点(911004),通知取完成，到达缓存架(911017), 通知放完成（带上位置）
	 *   报废-下线: 前往报废架前置点(911014)，等待通知下一步报废架(911005)，前往报废架前置点(911004),通知取完成，到达报废架下线(911020),等待操作完成离开
	 *   返修-缓存: 前往报废架前置点(911015)，等待通知下一步返修架(911006)，前往报废架前置点(911006),通知取完成，到达缓存架(911017), 通知放完成（带上位置）
	 *。 返修-上线: 前往报废架前置点(911015)，等待通知下一步返修架(911006)，前往报废架前置点(911006),通知取完成，上线前置点(911013), 等待通知，前往(911012), 上线前置点(911013),通知放完成（带上位置）
	 *。 新轴-上线: 前往新轴前置点(91118)，等待通知下一步新轴(91101)，前往新轴前置点(91118),通知取完成，上线前置点(911013), 等待通知，前往(911012), 上线前置点(911013),通知放完成
	 *。 旧轴-上线: 前往新轴前置点(91102)，等待通知下一步旧轴(91102)，前往新轴前置点(91119),通知取完成，上线前置点(911013), 等待通知，前往(911012), 上线前置点(911013),通知放完成
	 //*   新/旧-上线: 前往报废架前置点(911015)，等待通知下一步返修架(911006)，前往报废架前置点(911006),通知取完成，上线前置点(911013), 等待通知，前往(911012), 上线前置点(911013),通知放完成（带上位置）
	 * @param agvCallRequestParams
	 * @return
	 * @throws SchedulerException
	 */
	@PostMapping(value = "/agv/call")
	@Operation(summary = "AGV请求任务")
	//  车轴 1.185
	 // 0.166
	public AgvCallResult call(@RequestBody AgvCallRequestParams agvCallRequestParams) throws SchedulerException {
		try {
			log.info("自动任务Calling agv: {}", JSONObject.toJSONString(agvCallRequestParams));
			String taskName = createTaskName(agvCallRequestParams.getSrc(), agvCallRequestParams.getDes());
			String src = agvCallRequestParams.getSrc();
			String dest = agvCallRequestParams.getDes();
			Integer num = agvCallRequestParams.getSrcnum();
			List<AgvCallDataDto> data = agvCallRequestParams.getData();
			List<AgvCallDataDto> newData = Lists.newArrayList();
			log.info("接受到任务: {}---{}", src , dest);
			RobotJobEntity robotJob =  new RobotJobEntity();
			robotJob.setCron("0 * * * * ?");
			robotJob.setName(taskName + ":时间-" + DateUtil.format(new Date(), "yyyyMMddHH:mm:ss") );
			if (agvCallRequestParams.getData() != null) {
				robotJob.setRemark(JSONObject.toJSONString(agvCallRequestParams.getData()));
			}
			robotJob.setGroupId(6);
			String content ="{\"robotSn\":\"sr_002\",\"id\":null,\"formTitle\":\"运输工单上下文参数配置\",\"formName\":\"tickets_params_agv\",\"fields\":[{\"id\":45,\"name\":\"targetPosCode\",\"label\":\"目标点位编码\",\"type\":\"radio\",\"defaultValue\":null,\"currentValue\":\"LM34\",\"required\":true,\"min\":null,\"max\":null,\"pattern\":null,\"options\":[\"{\\\"label\\\":\\\"LM34\\\",\\\"value\\\":\\\"LM34\\\"}\"]},{\"id\":46,\"name\":\"sourcePosCode\",\"label\":\"起始点位编码\",\"type\":\"radio\",\"defaultValue\":null,\"currentValue\":\"LM23\",\"required\":true,\"min\":null,\"max\":null,\"pattern\":null,\"options\":[\"{\\\"label\\\":\\\"LM23\\\",\\\"value\\\":\\\"LM23\\\"}\"]}]}";
			content = content.replaceAll("LM34", dest).replaceAll("LM23", src);
			String zx = agvCallRequestParams.getZx();
			List<GoodsGroupEntity> goodsGroupEntities = goodsGroupService.list();
			List<GoodsBuffersEntity> goodsBuffersEntities = Lists.newArrayList();
			if (src.contains("911017")) {
				// 报废直接下线
				GoodsBuffersEntity startGroupName = null;
				GoodsBuffersEntity predGroupName = null;
				if (StrUtil.isEmpty(zx)) {
					zx = "77";
				}
				for (GoodsGroupEntity goodsGroupEntity: goodsGroupEntities) {
					List<GoodsBuffersEntity> list = goodsBuffersService.list(
							Wrappers.<GoodsBuffersEntity>lambdaQuery().like(GoodsBuffersEntity::getName, "-1")
									.eq(GoodsBuffersEntity::getGroupId, goodsGroupEntity.getId())
									.orderByDesc(GoodsBuffersEntity::getId)
					);
					String finalZx = zx;
					Optional<GoodsBuffersEntity> goodsBuffersEntity =
							list.stream().filter(t->
									t.getStoreName().equals(finalZx)).findFirst();
					if (goodsBuffersEntity.isPresent()) {
						startGroupName = goodsBuffersEntity.get();
						List<GoodsBuffersEntity> allGoods = goodsBuffersService.list(
								Wrappers.<GoodsBuffersEntity>lambdaQuery().eq(GoodsBuffersEntity::getGroupId, startGroupName.getGroupId())
										.eq(GoodsBuffersEntity::getStoreStatus, 1)
										.orderByDesc(GoodsBuffersEntity::getSn)
						);
						if (num > allGoods.size()) {
							log.info("缓存区没有缓存可以取，查询下一个");
							predGroupName = startGroupName;
							startGroupName = null;
							continue;
						}
						goodsBuffersEntities = allGoods;
					}
					if (startGroupName != null) {
						// 更新第一根
						if (StrUtil.isEmpty(zx)) {
							startGroupName.setStoreName(startGroupName.getStoreName());
						} else {
							startGroupName.setStoreName(zx);
						}

						goodsBuffersService.updateById(startGroupName);
						break;
					}
				}

				if (startGroupName == null && predGroupName != null) {
					List<GoodsBuffersEntity> allGoods = goodsBuffersService.list(
							Wrappers.<GoodsBuffersEntity>lambdaQuery().eq(GoodsBuffersEntity::getGroupId, predGroupName.getGroupId())
									.eq(GoodsBuffersEntity::getStoreStatus, 1)
					);
					goodsBuffersEntities = allGoods;
					num = goodsBuffersEntities.size();
				}
				//if (src.equals("911006")) {
				//	// 返修 缓存架 7
				//	goodsBuffersEntities = goodsBuffersService.list(Wrappers.<GoodsBuffersEntity>lambdaQuery()
				//			.eq(GoodsBuffersEntity::getStoreStatus, 1)
				//			.eq(GoodsBuffersEntity::getStoreName, "81")
				//			.orderByAsc(GoodsBuffersEntity::getSn));
				//} else {
				//
				//}
				//// 查询终点
				if(goodsBuffersEntities.size() > 0) {
					GoodsBuffersEntity goodsBuffersEntity = goodsBuffersEntities.get(
							Math.max(0, num-1));
					log.info("查询取的架子是：" + goodsBuffersEntity.getName());
					content = content.replaceAll(src, goodsBuffersEntity.getBindPosName());
					for (int i = 0; i < num; i++) {
						GoodsBuffersEntity saveGood = goodsBuffersEntities.get(i);
						AgvCallDataDto agvCallDataDto = JSONObject.parseObject(saveGood.getStoreData(), AgvCallDataDto.class);
						if (agvCallDataDto != null) {
							log.info("更新取状态:" + saveGood.getName());
							saveGood.setStoreStatus(0);
							if (StrUtil.isNotEmpty(zx)) {
								saveGood.setStoreName("");
							}
							//saveGood.setStoreData("");
							goodsBuffersService.updateById(saveGood);
							newData.add(agvCallDataDto);
						}

						// 增加日志
					}
					content = content.replaceAll(src, goodsBuffersEntity.getBindPosName());
				}
			} else if (dest.contains("911017") ) {
				// 缓存区放下去
				//if (src.equals("911005")) {
				//	// 报废-报废。8
				//	goodsBuffersEntities = goodsBuffersService.list(Wrappers.<GoodsBuffersEntity>lambdaQuery()
				//			.eq(GoodsBuffersEntity::getStoreStatus, 0)
				//			.eq(GoodsBuffersEntity::getStoreName, "91")
				//					.orderByAsc(GoodsBuffersEntity::getSn));
				//} else
					if (src.equals("911006")) {
					// 返修 缓存架 7
					goodsBuffersEntities = goodsBuffersService.list(Wrappers.<GoodsBuffersEntity>lambdaQuery()
							.eq(GoodsBuffersEntity::getStoreStatus, 0)
							.eq(GoodsBuffersEntity::getStoreName, "77")
							.orderByAsc(GoodsBuffersEntity::getSn));
				} else {
					GoodsBuffersEntity startGroupName = null;
					for (GoodsGroupEntity goodsGroupEntity: goodsGroupEntities) {
						List<GoodsBuffersEntity> list = goodsBuffersService.list(
								Wrappers.<GoodsBuffersEntity>lambdaQuery().
										like(GoodsBuffersEntity::getName, "-1")
										.eq(GoodsBuffersEntity::getStoreName, zx)
						);
						if (CollectionUtil.isEmpty(list)) {
							list = goodsBuffersService.list(
									Wrappers.<GoodsBuffersEntity>lambdaQuery().
											like(GoodsBuffersEntity::getName, "-1")
											.eq(GoodsBuffersEntity::getGroupId, goodsGroupEntity.getId())
							);
						}
						String finalZx1 = zx;
						Optional<GoodsBuffersEntity> goodsBuffersEntity =
								list.stream().filter(t->
										t.getStoreName().equals(finalZx1)).findFirst();
						if (goodsBuffersEntity.isPresent()) {
							startGroupName = goodsBuffersEntity.get();
							List<GoodsBuffersEntity> allGoods = goodsBuffersService.list(
									Wrappers.<GoodsBuffersEntity>lambdaQuery().eq(GoodsBuffersEntity::getGroupId, startGroupName.getGroupId())
											.eq(GoodsBuffersEntity::getStoreStatus, 0)
							);
							if (num > allGoods.size()) {
								log.info("缓存区没有缓存可以放，取查询下一个");
								startGroupName = null;
								continue;
							}
							goodsBuffersEntities = allGoods;
						} else {
							goodsBuffersEntity =
									list.stream().filter(t->
											t.getStoreStatus().equals(0)).findFirst();
							if (goodsBuffersEntity.isPresent()) {
								startGroupName = goodsBuffersEntity.get();
								List<GoodsBuffersEntity> allGoods = goodsBuffersService.list(
										Wrappers.<GoodsBuffersEntity>lambdaQuery().eq(GoodsBuffersEntity::getGroupId, startGroupName.getGroupId())
												.eq(GoodsBuffersEntity::getStoreStatus, 0)
								);
								if (num > allGoods.size()) {
									log.info("缓存区没有缓存可以放，取查询下一个");
									startGroupName = null;
									continue;
								}
								goodsBuffersEntities = allGoods;
							}
						}
						if (startGroupName != null) {
							// 更新第一更
							startGroupName.setStoreName(zx);
							goodsBuffersService.updateById(startGroupName);
							break;
						}
					}
					// 终点是缓存区
				}
					if(goodsBuffersEntities.size() > 0) {
						GoodsBuffersEntity goodsBuffersEntity = goodsBuffersEntities.get(0);
						log.info("查询存放的架子是：" + goodsBuffersEntity.getName());
						content = content.replaceAll(dest, goodsBuffersEntity.getBindPosName());
						if (CollectionUtil.isNotEmpty(data)  && data.size() > 0) {
							for (int i = 0; i < num; i++) {
								GoodsBuffersEntity saveGood = goodsBuffersEntities.get(i);
								log.info("更新存放状态:" + saveGood.getName());
								AgvCallDataDto agvCallDataDto = data.get(i);
								if (agvCallDataDto != null) {
									agvCallDataDto.setPos(saveGood.getName());
									saveGood.setStoreStatus(1);
									saveGood.setStoreData(JSONObject.toJSONString(agvCallDataDto));
									if (StrUtil.isNotEmpty(zx)) {
										saveGood.setStoreName(zx);
									}
									goodsBuffersService.updateById(saveGood);
									newData.add(agvCallDataDto);
									// 增加日志
								}
							}
						}
						content = content.replaceAll(dest, goodsBuffersEntity.getBindPosName());
					}

		}
			if (newData.isEmpty()) {
				newData  = agvCallRequestParams.getData();
			}
			FormConfigModalDto jsonArray = JSONObject.parseObject(content, FormConfigModalDto.class);
			List<FormFieldConfigModalDto> formFieldConfigModalDtos = jsonArray.getFields();
			FormFieldConfigModalDto dto = new FormFieldConfigModalDto();

			dto = new FormFieldConfigModalDto();
			dto.setLabel("srcnum");
			dto.setName("srcnum");
			dto.setCurrentValue("" + num);
			formFieldConfigModalDtos.add(dto);

			dto = new FormFieldConfigModalDto();
			dto.setLabel("pjData");
			dto.setName("pjData");
			dto.setCurrentValue(JSONObject.toJSONString(newData));
			formFieldConfigModalDtos.add(dto);

			dto = new FormFieldConfigModalDto();
			dto.setLabel("auto");
			dto.setName("auto");
			//dto.setCurrentValue("0");
			dto.setCurrentValue("1");
			formFieldConfigModalDtos.add(dto);

			jsonArray.setFields(formFieldConfigModalDtos);
			robotJob.setContent(JSONObject.toJSONString(jsonArray));
			//robotJobService.save(robotJob);

			//SysJob sysJob = sysJobService.addJobByRobotJob(robotJob.getName(), robotJob.getCron(), String.valueOf(robotJob.getId()));
			//if (sysJob  != null) {
				// 先查询执行的顺序
				JobCachesEntity jobCachesEntity = new JobCachesEntity();
				// 两边都分配固定的分组id
				jobCachesEntity.setGroupId(6);
				jobCachesEntity.setTaskName(createTaskName(src, dest));
				jobCachesEntity.setJobType(jobCachesEntity.getTaskName());
				// 执行的顺序
				Long maxSn = jobCachesService.getMaxSn(6);
				jobCachesEntity.setSn((int) (1 + maxSn));
				jobCachesEntity.setTaskContent(robotJob.getContent());
				jobCachesService.save(jobCachesEntity);
				SpringUtil.getApplicationContext().publishEvent(new SubscriptTopicDto("jobCaches"));
			//}
			// 等待
			try {
				TimeUnit.SECONDS.sleep(2);
			}catch (Exception e) {
			}
			 //工单查询
			// 查询缓存记录
			//Cache<Integer, RobotEntity> executeRobot = SpringUtil.getBean("executeTaskRobot");
			//RobotEntity robotEntity = executeRobot.getIfPresent(robotJob.getId());
			//if (robotEntity == null) {
			//	return AgvCallResult.builder()
			//			.ret(false)
			//			.sbID("")
			//			.message("")
			//			.build();
			//}
			return AgvCallResult.builder()
					.ret(true)
					.message("")
					.sbID("sr_agv2").build();
		} catch (Exception e) {
			log.info("数据异常无法解析:" + e.getMessage());
		}
		return AgvCallResult.builder()
				.ret(false)
				.sbID("")
				.message("操作异常")
				.build();
	}


	public String createTaskName(String src, String des) {
		String taskName = "调试任务";
		if (src.equals("91101") && des.equals("911012")) {
			taskName = "新轴上线";
		} else if (src.equals("91102")&& des.equals("911012")) {
			taskName = "旧轴上线";
		} else if (src.equals("91102") && des.equals("911017")) {
			taskName = "旧轴上缓存架";
		} else if (src.equals("911005") && des.equals("911020")) {
			taskName = "报废轴下线";
		} else if (src.equals("911017") && des.equals("911012")) {
			taskName = "缓存架上线";
		} else if (src.equals("911006") && des.equals("911012")) {
			taskName = "返修上线";
		} else if (src.equals("911006") && des.equals("911017")) {
			taskName = "返修上缓存架";
		} else if (src.equals("911008") && des.equals("911009")) {
			taskName = "南面(货车)";
		} else if (src.equals("911007") && des.equals("911009")) {
			taskName = "北面(客货车)";
		}  else if (src.equals("911008") && des.equals("911007")) {
			taskName = "南面转北面";
		}  else if (src.equals("911007") && des.equals("911008")) {
			taskName = "北面转南面";
		}
		return taskName;
	}

	@PostMapping(value = "/agv/arriveResponse")
	public AgvCallResult arriveResponse(@RequestBody AgvArriveResponseParams agvArriveResponseParams,
										HttpServletRequest request) {
		try {
			String ip = getClientIpAddress(request);
			log.info("arriveResponse: {}----{}", ip, JSONObject.toJSONString(agvArriveResponseParams));
		} catch (Exception e) {
			log.info("获取ip异常");
		}
		RobotNextStepDto robotNextStepDto = new RobotNextStepDto();
		robotNextStepDto.setPosCode(agvArriveResponseParams.getArrivePos());
		robotNextStepDto.setClientId(agvArriveResponseParams.getSbID());
		SpringUtil.getApplicationContext().publishEvent(robotNextStepDto);
		return AgvCallResult.builder()
				.ret(true).sbID(agvArriveResponseParams.getSbID()).build();
	}

	@PostMapping(value = "/agv/pick")
	@Deprecated
	public AgvCallResult pick(@RequestBody AgvPickParams agvPickParams) {
		AgvCallResult agvCallResult = agvDao.pick(agvPickParams);
		log.info("pick: {}", agvCallResult.toString());
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("faultPos", "911013");
		jsonObject.put("src", "911013");
		jsonObject.put("desc", "911013");
		jsonObject.put("sbID", "sr_agv1");
		jsonObject.put("problem", "急停按钮触发");
		HttpEntity<String> strEntity = new HttpEntity<String>(jsonObject.toString(), headers);
		String result = restTemplate.postForObject("", strEntity, String.class);
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}

	@PostMapping(value = "/agv/store")
	@Deprecated
	public AgvCallResult store(@RequestBody AgvStoreParams agvStoreParams) {
		AgvCallResult agvCallResult = agvDao.store(agvStoreParams);
		log.info("store: {}", agvCallResult.toString());
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}


	@PostMapping(value = "/scx/start")
	@Deprecated
	public AgvCallResult start(@RequestBody ScxStatus status) {
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}

	@PostMapping(value = "/scx/stop")
	@Deprecated
	public AgvCallResult stop(@RequestBody ScxStatus status) {
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}


	@PostMapping(value = "/agv/fault")
	@Deprecated
	public AgvCallResult fault() {
		RestTemplate restTemplate = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("faultPos", "911013");
		jsonObject.put("src", "911013");
		jsonObject.put("desc", "911013");
		jsonObject.put("sbID", "sr_agv1");
		jsonObject.put("problem", "急停按钮触发");

		HttpEntity<String> strEntity = new HttpEntity<String>(jsonObject.toString(), headers);
		String result = restTemplate.postForObject("http://276to9673ki4.vicp.fun/api/v1/centreApp/agv/fault/", strEntity, String.class);

		//AgvFaultParams agvFaultParams = new AgvFaultParams();
		//agvFaultParams.setFaultPos("91119");
		//agvFaultParams.setSrc("91119");
		//agvFaultParams.setDesc("91119");
		//agvFaultParams.setSbID("sr_agv1");
		//agvFaultParams.setProblem("急停触发");
		//agvDao.fault(agvFaultParams);


		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}



	@PostMapping(value = "/agv/arrive")
	@Deprecated
	public AgvCallResult arrive(@RequestBody AgvArriveResponseParams agvArriveResponseParams) {
		RestTemplate restTemplate = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("sbID", agvArriveResponseParams.getSbID());
		jsonObject.put("fktime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
		jsonObject.put("arrivePos", "91119");
		HttpEntity<String> strEntity = new HttpEntity<String>(jsonObject.toString(), headers);
		String result = restTemplate.postForObject("http://276to9673ki4.vicp.fun/api/v1/centreApp/agv/arrive/",
				strEntity, String.class);
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}


	@PostMapping(value = "/agv/workMode")
	@Deprecated
	public AgvCallResult workMode(@RequestBody AgvWorkModeParams workModeParams) {
		AgvCallResult agvCallResult = agvDao.workmode(workModeParams);
		log.info("work: {}", agvCallResult.toString());
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}
	@PostMapping(value = "/agv/powerOn")
	@Deprecated
	public AgvCallResult powerOn(@RequestBody PowerRobotParams powerRobotParams) {
		RestTemplate restTemplate = new RestTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("sbID", "sr_agv1");
		jsonObject.put("fktime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));

		HttpEntity<String> strEntity = new HttpEntity<String>(jsonObject.toString(), headers);
		String result = restTemplate.postForObject("http://276to9673ki4.vicp.fun/api/v1/incomeDecomposeApp/agv/poweron", strEntity, String.class);


		//CallAgvResult agvCallResult = agvDao.powerOn(powerRobotParams);
		//log.info("work: {}", agvCallResult.toString());
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}

	@PostMapping(value = "/agv/powerOff")
	@Deprecated
	public AgvCallResult powerOff(@RequestBody PowerRobotParams powerRobotParams) {
		CallAgvResult agvCallResult = agvDao.powerOff(powerRobotParams);
		log.info("work: {}", agvCallResult.toString());
		return AgvCallResult.builder()
				.ret(true).sbID("sr_agv1").build();
	}
	// 轮对。3.241 3.242 道闸
	// 轮轴 0.241 0.242
	@GetMapping(value = "/agv/currentPos")
	@Operation(summary = "获取AGV当前坐标状态")
	public R<List<RobotPosDto>> currentPos() {
		// 清除错误、 重定位、 订单清除、 急停、 调度上下线(清除控制权)
		List<RobotPosDto> list = Lists.newArrayList();
		List<RobotEntity> robotEntities = robotService.list();
		Cache<String, RobotClientSummaryDto> posInfoDtoCache = SpringUtil.getBean("robotCache");
		for (RobotEntity robotEntity : robotEntities) {
			RobotClientSummaryDto posInfoDto = posInfoDtoCache.getIfPresent(robotEntity.getRobotSn());
			RobotPosDto robotPosDto = new RobotPosDto();
			if (posInfoDto != null) {
				robotPosDto.setPosX(String.valueOf(posInfoDto.getPosition().getLaserPos().getX()));
				robotPosDto.setPosY(String.valueOf(posInfoDto.getPosition().getLaserPos().getY()));
				robotPosDto.setYaw(String.valueOf(posInfoDto.getPosition().getLaserPos().getYaw()));
				robotPosDto.setAgvName(posInfoDto.getStatus().getName());
				robotPosDto.setAgvSn(posInfoDto.getStatus().getSn());
				robotPosDto.setOnlineState(posInfoDto.getStatus().getOnlineStatusStr());
				robotPosDto.setRunningState(posInfoDto.getStatus().getWorkStatusStr());
				robotPosDto.setAlarmState("");
				try {
					robotPosDto.setJackIsFull(Optional.ofNullable(posInfoDto.getStatus().getIsFull()).orElse(false));
				} catch (Exception e) {
					//throw new RuntimeException(e);
					robotPosDto.setJackIsFull(false);
				}
			} else {
				robotPosDto.setPosX("0");
				robotPosDto.setPosY("0");
				robotPosDto.setYaw("0");
				robotPosDto.setAgvName(robotEntity.getRobotName());
				robotPosDto.setAgvSn(robotEntity.getRobotSn());
				robotPosDto.setOnlineState("离线");
				robotPosDto.setRunningState("空闲");
				robotPosDto.setAlarmState("");
				robotPosDto.setJackIsFull(false);
			}
			list.add(robotPosDto);
		}
		return R.ok(list);
	}


	/**
	 * 对轮 172.24.3.241
	 *     172.24.3.242
	 * @return
	 */

	@GetMapping(value = "/agv/gateStatus")
	@Operation(summary = "道闸状态")
	public R<List<GateStatusDto>> gateStatus() {
		List<GateStatusDto> list = Lists.newArrayList();
		GateStatusDto dto = new GateStatusDto();
		dto.setIp("172.24.3.241");
		dto.setStatus(1);
		list.add(dto);
		dto = new GateStatusDto();
		dto.setIp("172.24.3.242");
		dto.setStatus(0);
		list.add(dto);
		return R.ok(list);
	}



	@PostMapping(value = "/agv/semiAutomatic")
	@Operation(summary = "AGV请求任务-半自动任务模式")
	public R semiAutomatic(@RequestBody SemiAutomaticParams agvCallRequestParams) {
		try {
			log.info("半自动任务模式AGV: {}", JSONObject.toJSONString(agvCallRequestParams));
			String taskName = createTaskName(agvCallRequestParams.getSrc(), agvCallRequestParams.getDes());
			String src = agvCallRequestParams.getSrc();
			String dest = agvCallRequestParams.getDes();
			Integer num = Optional.of(agvCallRequestParams.getSrcnum()).orElse(1);
			Long maxSn = jobCachesService.getMaxSn(6);
			for (int i = 0; i < num; i++) {
				// 组建任务数据
				List<AgvCallDataDto> newData = agvCallRequestParams.getData();
				RobotJobEntity robotJob =  new RobotJobEntity();
				robotJob.setCron("0 * * * * ?");
				robotJob.setName(taskName + ":时间-" + DateUtil.format(new Date(), "yyyyMMddHH:mm:ss") );
				if (agvCallRequestParams.getData() != null) {
					robotJob.setRemark(JSONObject.toJSONString(agvCallRequestParams.getData()));
				}
				robotJob.setGroupId(6);
				String content ="{\"robotSn\":\"sr_002\",\"id\":null,\"formTitle\":\"运输工单上下文参数配置\",\"formName\":\"tickets_params_agv\",\"fields\":[{\"id\":45,\"name\":\"targetPosCode\",\"label\":\"目标点位编码\",\"type\":\"radio\",\"defaultValue\":null,\"currentValue\":\"LM34\",\"required\":true,\"min\":null,\"max\":null,\"pattern\":null,\"options\":[\"{\\\"label\\\":\\\"LM34\\\",\\\"value\\\":\\\"LM34\\\"}\"]},{\"id\":46,\"name\":\"sourcePosCode\",\"label\":\"起始点位编码\",\"type\":\"radio\",\"defaultValue\":null,\"currentValue\":\"LM23\",\"required\":true,\"min\":null,\"max\":null,\"pattern\":null,\"options\":[\"{\\\"label\\\":\\\"LM23\\\",\\\"value\\\":\\\"LM23\\\"}\"]}]}";
				content = content.replaceAll("LM34", dest).replaceAll("LM23", src);

				FormConfigModalDto jsonArray = JSONObject.parseObject(content, FormConfigModalDto.class);
				List<FormFieldConfigModalDto> formFieldConfigModalDtos = jsonArray.getFields();
				FormFieldConfigModalDto dto = new FormFieldConfigModalDto();

				dto = new FormFieldConfigModalDto();
				dto.setLabel("srcnum");
				dto.setName("srcnum");
				dto.setCurrentValue("4");
				formFieldConfigModalDtos.add(dto);
				dto = new FormFieldConfigModalDto();
				dto.setLabel("pjData");
				dto.setName("pjData");
				dto.setCurrentValue(JSONObject.toJSONString(newData));
				formFieldConfigModalDtos.add(dto);
				dto = new FormFieldConfigModalDto();
				dto.setLabel("auto");
				dto.setName("auto");
				// 1-自动 0-半自动
				dto.setCurrentValue("0");
				formFieldConfigModalDtos.add(dto);
				jsonArray.setFields(formFieldConfigModalDtos);
				robotJob.setContent(JSONObject.toJSONString(jsonArray));
				// 先查询执行的顺序
				JobCachesEntity jobCachesEntity = new  JobCachesEntity();
				// 两边都分配固定的分组id
				jobCachesEntity.setGroupId(6);
				jobCachesEntity.setTaskName(createTaskName(src, dest));
				jobCachesEntity.setJobType(jobCachesEntity.getTaskName());
				// 执行的顺序
				jobCachesEntity.setSn((int) (i + 1 + maxSn));
				jobCachesEntity.setTaskContent(robotJob.getContent());
				jobCachesService.save(jobCachesEntity);
				SpringUtil.getApplicationContext().publishEvent(new SubscriptTopicDto("jobCaches"));
			}
			return R.ok("任务已经添加，请等待执行");
		} catch (Exception e) {
			log.info("数据异常无法解析:" + e.getMessage());
			return R.failed("呼叫失败");
		}
	}


	public String getClientIpAddress(HttpServletRequest request) {
		String ipAddress = request.getHeader("X-Forwarded-For");
		if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) {
			ipAddress = request.getRemoteAddr();
		}
		return ipAddress;
	}





	@GetMapping(value = "/agv/storeBuffersStatus")
	@Operation(summary = "缓存架状态")
	public R<List<StoreStatusDto>> storeBuffersStatus() {
		List<StoreStatusDto> list = Lists.newArrayList();
		LambdaQueryWrapper<GoodsBuffersEntity> wrapper = Wrappers.lambdaQuery();
		List<GoodsBuffersEntity> goodsBuffersEntities = goodsBuffersService.list(
				wrapper.orderByAsc(GoodsBuffersEntity::getName)
						.orderByAsc(GoodsBuffersEntity::getSn)
		);
		for (GoodsBuffersEntity goodsBuffersEntity : goodsBuffersEntities) {
			StoreStatusDto storeStatusDto = new StoreStatusDto();
			BeanUtil.copyProperties(goodsBuffersEntity, storeStatusDto);
			storeStatusDto.setStoreStatusStr(storeStatusDto.getStoreStatus() == 1 ? "已存放":"未存放");
			list.add(storeStatusDto);
		}
		return R.ok(list);
	}


	@PostMapping(value = "/agv/updateStoreStatus")
	@Operation(summary = "更新缓存架状态")
	public AgvCallResult updateStoreStatus(@RequestBody StoreStatusDto storeStatusDto) {
		GoodsBuffersEntity goodsBuffersEntity = goodsBuffersService.getOne(Wrappers.<GoodsBuffersEntity>lambdaQuery().eq(GoodsBuffersEntity::getName, storeStatusDto.getName())
				.last("limit 1"));
		if (goodsBuffersEntity == null) {
			return AgvCallResult.builder().ret(false).message("未找到相关记录").build();
		}
		if (storeStatusDto.getName().contains("-1")) {
			String preName = storeStatusDto.getName().split("-")[0];
			List<GoodsBuffersEntity> list = goodsBuffersService.list(
					Wrappers.<GoodsBuffersEntity>lambdaQuery()
							.like(GoodsBuffersEntity::getName, preName+ "-"));
			for (GoodsBuffersEntity entity : list) {
				goodsBuffersService.update(Wrappers.<GoodsBuffersEntity>lambdaUpdate()
						.eq(GoodsBuffersEntity::getId, entity.getId())
						.set(GoodsBuffersEntity::getStoreName, "")
						.set(GoodsBuffersEntity::getStoreStatus, 0));
			}
		}
		goodsBuffersEntity.setStoreStatus(storeStatusDto.getStoreStatus());
		goodsBuffersService.updateById(goodsBuffersEntity);
		return AgvCallResult.builder().ret(true).message("更新成功").build();
	}


	@DeleteMapping(value = "/agv/deleteStoreStatus")
	@Operation(summary = "删除缓存架状态")
	public AgvCallResult deleteStoreStatus(@RequestBody  DeleteStoreStatusDto dto) {
		GoodsBuffersEntity goodsBuffersEntity = goodsBuffersService
				.getOne(Wrappers.<GoodsBuffersEntity>lambdaQuery()
						.eq(GoodsBuffersEntity::getName, dto.getName())
				.last("limit 1"));
		if (goodsBuffersEntity == null) {
			return AgvCallResult.builder().ret(false).message("未找到相关记录").build();
		}
		if (dto.getName().contains("-1")) {
			String preName = dto.getName().split("-")[0];
			List<GoodsBuffersEntity> list = goodsBuffersService.list(
					Wrappers.<GoodsBuffersEntity>lambdaQuery()
							.like(GoodsBuffersEntity::getName, preName+ "-"));
			for (GoodsBuffersEntity entity : list) {
				goodsBuffersService.update(Wrappers.<GoodsBuffersEntity>lambdaUpdate()
						.eq(GoodsBuffersEntity::getId, entity.getId())
						.set(GoodsBuffersEntity::getStoreName, "")
						.set(GoodsBuffersEntity::getStoreStatus, 0));
			}
		}
		goodsBuffersEntity.setStoreName("");
		goodsBuffersEntity.setStoreStatus(0);
		goodsBuffersService.updateById(goodsBuffersEntity);

		return AgvCallResult.builder().ret(true).message("更新成功").build();
	}



}
